home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0992.ARJ / MENUBAR.C < prev    next >
Text File  |  1992-08-02  |  13KB  |  409 lines

  1. /* ---------------- menubar.c ------------------ */
  2.  
  3. #include "dflat.h"
  4.  
  5. static void reset_menubar(WINDOW);
  6.  
  7. static struct {
  8.     int x1, x2;     /* position in menu bar */
  9.     char sc;        /* shortcut key value   */
  10. } menu[10];
  11. static int mctr;
  12.  
  13. MBAR *ActiveMenuBar;
  14. static MENU *ActiveMenu;
  15.  
  16. static WINDOW mwnd;
  17. static BOOL Selecting;
  18.  
  19. static WINDOW Cascaders[MAXCASCADES];
  20. static int casc;
  21. static WINDOW GetDocFocus(void);
  22.  
  23. /* ----------- SETFOCUS Message ----------- */
  24. static int SetFocusMsg(WINDOW wnd, PARAM p1)
  25. {
  26.     int rtn;
  27.     rtn = BaseWndProc(MENUBAR, wnd, SETFOCUS, p1, 0);
  28.     if (!(int)p1)
  29.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  30.     return rtn;
  31. }
  32.  
  33. /* --------- BUILDMENU Message --------- */
  34. static void BuildMenuMsg(WINDOW wnd, PARAM p1)
  35. {
  36.     int offset = 3;
  37.     reset_menubar(wnd);
  38.     mctr = 0;
  39.     ActiveMenuBar = (MBAR *) p1;
  40.     ActiveMenu = ActiveMenuBar->PullDown;
  41.     while (ActiveMenu->Title != NULL &&
  42.             ActiveMenu->Title != (void*)-1)    {
  43.         char *cp;
  44.         if (strlen(GetText(wnd)+offset) <
  45.                 strlen(ActiveMenu->Title)+3)
  46.             break;
  47.         GetText(wnd) = DFrealloc(GetText(wnd),
  48.             strlen(GetText(wnd))+5);
  49.         memmove(GetText(wnd) + offset+4, GetText(wnd) + offset,
  50.                 strlen(GetText(wnd))-offset+1);
  51.         CopyCommand(GetText(wnd)+offset,ActiveMenu->Title,FALSE,
  52.                 wnd->WindowColors [STD_COLOR] [BG]);
  53.         menu[mctr].x1 = offset;
  54.         offset += strlen(ActiveMenu->Title) + (3+MSPACE);
  55.         menu[mctr].x2 = offset-MSPACE;
  56.         cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
  57.         if (cp)
  58.             menu[mctr].sc = tolower(*(cp+1));
  59.         mctr++;
  60.         ActiveMenu++;
  61.     }
  62.     ActiveMenu = ActiveMenuBar->PullDown;
  63. }
  64.  
  65. /* ---------- PAINT Message ---------- */
  66. static void PaintMsg(WINDOW wnd)
  67. {
  68.     if (Selecting)
  69.         return;
  70.     if (wnd == inFocus)
  71.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  72.     SetStandardColor(wnd);
  73.     wputs(wnd, GetText(wnd), 0, 0);
  74.     if (ActiveMenuBar->ActiveSelection != -1 &&
  75.             (wnd == inFocus || mwnd != NULL))    {
  76.         char *sel, *cp;
  77.         int offset, offset1;
  78.  
  79.         sel = DFmalloc(200);
  80.         offset=menu[ActiveMenuBar->ActiveSelection].x1;
  81.         offset1=menu[ActiveMenuBar->ActiveSelection].x2;
  82.         GetText(wnd)[offset1] = '\0';
  83.         SetReverseColor(wnd);
  84.         memset(sel, '\0', 200);
  85.         strcpy(sel, GetText(wnd)+offset);
  86.         cp = strchr(sel, CHANGECOLOR);
  87.         if (cp != NULL)
  88.             *(cp + 2) = background | 0x80;
  89.         wputs(wnd, sel,
  90.             offset-ActiveMenuBar->ActiveSelection*4, 0);
  91.         GetText(wnd)[offset1] = ' ';
  92.         if (mwnd == NULL && wnd == inFocus) {
  93.             char *st = ActiveMenu
  94.                 [ActiveMenuBar->ActiveSelection].StatusText;
  95.             if (st != NULL)
  96.                 SendMessage(GetParent(wnd), ADDSTATUS,
  97.                     (PARAM)st, 0);
  98.         }
  99.         free(sel);
  100.     }
  101. }
  102.  
  103. /* ------------ KEYBOARD Message ------------- */
  104. static void KeyboardMsg(WINDOW wnd, PARAM p1)
  105. {
  106.     MENU *mnu;
  107.     int sel;
  108.     if (mwnd == NULL)    {
  109.         /* ----- search for menu bar shortcut keys ---- */
  110.         int c = tolower((int)p1);
  111.         int a = AltConvert((int)p1);
  112.         int j;
  113.         for (j = 0; j < mctr; j++)    {
  114.             if ((inFocus == wnd && menu[j].sc == c) ||
  115.                     (a && menu[j].sc == a))    {
  116.                 SendMessage(wnd, SETFOCUS, TRUE, 0);
  117.                 SendMessage(wnd, MB_SELECTION, j, 0);
  118.                 return;
  119.             }
  120.         }
  121.     }
  122.     /* -------- search for accelerator keys -------- */
  123.     mnu = ActiveMenu;
  124.     while (mnu->Title != (void *)-1)    {
  125.         struct PopDown *pd = mnu->Selections;
  126.         if (mnu->PrepMenu)
  127.             (*(mnu->PrepMenu))(GetDocFocus(), mnu);
  128.         while (pd->SelectionTitle != NULL)    {
  129.             if (pd->Accelerator == (int) p1)    {
  130.                 if (pd->Attrib & INACTIVE)
  131.                     beep();
  132.                 else    {
  133.                     if (pd->Attrib & TOGGLE)
  134.                         pd->Attrib ^= CHECKED;
  135.                     SendMessage(GetDocFocus(),
  136.                         SETFOCUS, TRUE, 0);
  137.                     PostMessage(GetParent(wnd),
  138.                         COMMAND, pd->ActionId, 0);
  139.                 }
  140.                 return;
  141.             }
  142.             pd++;
  143.         }
  144.         mnu++;
  145.     }
  146.     switch ((int)p1)    {
  147.         case F1:
  148.             if (ActiveMenu == NULL || ActiveMenuBar == NULL)
  149.                 break;
  150.             sel = ActiveMenuBar->ActiveSelection;
  151.             if (sel == -1)    {
  152.                 BaseWndProc(MENUBAR, wnd, KEYBOARD, F1, 0);
  153.                 return;
  154.             }
  155.             mnu = ActiveMenu+sel;
  156.             if (mwnd == NULL ||
  157.                     mnu->Selections[0].SelectionTitle == NULL) {
  158.                    DisplayHelp(wnd,mnu->Title+1);
  159.                 return;
  160.             }
  161.             break;
  162.         case '\r':
  163.             if (mwnd == NULL &&
  164.                     ActiveMenuBar->ActiveSelection != -1)
  165.                 SendMessage(wnd, MB_SELECTION,
  166.                     ActiveMenuBar->ActiveSelection, 0);
  167.             break;
  168.         case F10:
  169.             if (wnd != inFocus && mwnd == NULL)    {
  170.                 SendMessage(wnd, SETFOCUS, TRUE, 0);
  171.                 if ( ActiveMenuBar->ActiveSelection == -1)
  172.                     ActiveMenuBar->ActiveSelection = 0;
  173.                 SendMessage(wnd, PAINT, 0, 0);
  174.                 break;
  175.             }
  176.             /* ------- fall through ------- */
  177.         case ESC:
  178.             if (inFocus == wnd && mwnd == NULL)    {
  179.                 ActiveMenuBar->ActiveSelection = -1;
  180.                 SendMessage(GetDocFocus(),SETFOCUS,TRUE,0);
  181.                 SendMessage(wnd, PAINT, 0, 0);
  182.             }
  183.             break;
  184.         case FWD:
  185.             ActiveMenuBar->ActiveSelection++;
  186.             if (ActiveMenuBar->ActiveSelection == mctr)
  187.                 ActiveMenuBar->ActiveSelection = 0;
  188.             if (mwnd != NULL)
  189.                 SendMessage(wnd, MB_SELECTION,
  190.                     ActiveMenuBar->ActiveSelection, 0);
  191.             else 
  192.                 SendMessage(wnd, PAINT, 0, 0);
  193.             break;
  194.         case BS:
  195.             if (ActiveMenuBar->ActiveSelection == 0 ||
  196.                     ActiveMenuBar->ActiveSelection == -1)
  197.                 ActiveMenuBar->ActiveSelection = mctr;
  198.             --ActiveMenuBar->ActiveSelection;
  199.             if (mwnd != NULL)
  200.                 SendMessage(wnd, MB_SELECTION,
  201.                     ActiveMenuBar->ActiveSelection, 0);
  202.             else 
  203.                 SendMessage(wnd, PAINT, 0, 0);
  204.             break;
  205.         default:
  206.             break;
  207.     }
  208. }
  209.  
  210. /* --------------- LEFT_BUTTON Message ---------- */
  211. static void LeftButtonMsg(WINDOW wnd, PARAM p1)
  212. {
  213.     int i;
  214.     int mx = (int) p1 - GetLeft(wnd);
  215.     /* --- compute the selection that the left button hit --- */
  216.     for (i = 0; i < mctr; i++)
  217.         if (mx >= menu[i].x1-4*i &&
  218.                 mx <= menu[i].x2-4*i-5)
  219.             break;
  220.     if (i < mctr)
  221.         if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL)
  222.             SendMessage(wnd, MB_SELECTION, i, 0);
  223. }
  224.  
  225. /* -------------- MB_SELECTION Message -------------- */
  226. static void SelectionMsg(WINDOW wnd, PARAM p1, PARAM p2)
  227. {
  228.     int wd, mx, my;
  229.     MENU *mnu;
  230.  
  231.     if (!p2)    {
  232.         ActiveMenuBar->ActiveSelection = -1;
  233.         SendMessage(wnd, PAINT, 0, 0);
  234.     }
  235.     Selecting = TRUE;
  236.     mnu = ActiveMenu+(int)p1;
  237.     if (mnu->PrepMenu != NULL)
  238.         (*(mnu->PrepMenu))(GetDocFocus(), mnu);
  239.     wd = MenuWidth(mnu->Selections);
  240.     if (p2)    {
  241.         int brd = GetRight(wnd);
  242.         mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1;
  243.         if (mx + wd > brd)
  244.             mx = brd - wd;
  245.         my = GetTop(mwnd) + mwnd->selection;
  246.     }
  247.     else    {
  248.         int offset = menu[(int)p1].x1 - 4 * (int)p1;
  249.         if (mwnd != NULL)
  250.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  251.         ActiveMenuBar->ActiveSelection = (int) p1;
  252.         if (offset > WindowWidth(wnd)-wd)
  253.             offset = WindowWidth(wnd)-wd;
  254.         mx = GetLeft(wnd)+offset;
  255.         my = GetTop(wnd)+1;
  256.     }
  257.     mwnd = CreateWindow(POPDOWNMENU, NULL,
  258.                 mx, my,
  259.                 MenuHeight(mnu->Selections),
  260.                 wd,
  261.                 NULL,
  262.                 wnd,
  263.                 NULL,
  264.                 SHADOW);
  265.     if (!p2)    {
  266.         Selecting = FALSE;
  267.         SendMessage(wnd, PAINT, 0, 0);
  268.         Selecting = TRUE;
  269.     }
  270.     if (mnu->Selections[0].SelectionTitle != NULL)    {
  271.         SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
  272.         SendMessage(mwnd, SETFOCUS, TRUE, 0);
  273.         SendMessage(mwnd, SHOW_WINDOW, 0, 0);
  274.     }
  275.     Selecting = FALSE;
  276. }
  277.  
  278. /* --------- COMMAND Message ---------- */
  279. static void CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
  280. {
  281.     if (p1 == ID_HELP)    {
  282.         BaseWndProc(MENUBAR, wnd, COMMAND, p1, p2);
  283.         return;
  284.     }
  285.     if (isCascadedCommand(ActiveMenuBar, (int)p1))    {
  286.         /* find the cascaded menu based on command id in p1 */
  287.         MENU *mnu = ActiveMenu+mctr;
  288.         while (mnu->Title != (void *)-1)    {
  289.             if (mnu->CascadeId == (int) p1)    {
  290.                 if (casc < MAXCASCADES)    {
  291.                     Cascaders[casc++] = mwnd;
  292.                     SendMessage(wnd, MB_SELECTION,
  293.                         (PARAM)(mnu-ActiveMenu), TRUE);
  294.                 }
  295.                 break;
  296.             }
  297.             mnu++;
  298.         }
  299.     }
  300.     else     {
  301.         if (mwnd != NULL)
  302.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  303.         SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
  304.         PostMessage(GetParent(wnd), COMMAND, p1, p2);
  305.     }
  306. }
  307.  
  308. /* --------------- CLOSE_POPDOWN Message --------------- */
  309. static void ClosePopdownMsg(WINDOW wnd)
  310. {
  311.     if (casc > 0)
  312.         SendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0);
  313.     else     {
  314.         mwnd = NULL;
  315.         ActiveMenuBar->ActiveSelection = -1;
  316.         if (!Selecting)    {
  317.             SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
  318.             SendMessage(wnd, PAINT, 0, 0);
  319.         }
  320.     }
  321. }
  322.  
  323. /* ---------------- CLOSE_WINDOW Message --------------- */
  324. static void CloseWindowMsg(WINDOW wnd)
  325. {
  326.     if (GetText(wnd) != NULL)    {
  327.         free(GetText(wnd));
  328.         GetText(wnd) = NULL;
  329.     }
  330.     mctr = 0;
  331.     ActiveMenuBar->ActiveSelection = -1;
  332.     ActiveMenu = NULL;
  333.     ActiveMenuBar = NULL;
  334. }
  335.  
  336. /* --- Window processing module for MENUBAR window class --- */
  337. int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  338. {
  339.     int rtn;
  340.  
  341.     switch (msg)    {
  342.         case CREATE_WINDOW:
  343.             reset_menubar(wnd);
  344.             break;
  345.         case SETFOCUS:
  346.             return SetFocusMsg(wnd, p1);
  347.         case BUILDMENU:
  348.             BuildMenuMsg(wnd, p1);
  349.             break;
  350.         case PAINT:    
  351.             if (!isVisible(wnd) || GetText(wnd) == NULL)
  352.                 break;
  353.             PaintMsg(wnd);
  354.             return FALSE;
  355.         case BORDER:
  356.             if (mwnd == NULL)
  357.                 SendMessage(wnd, PAINT, 0, 0);
  358.             return TRUE;
  359.         case KEYBOARD:
  360.             KeyboardMsg(wnd, p1);
  361.             return TRUE;
  362.         case LEFT_BUTTON:
  363.             LeftButtonMsg(wnd, p1);
  364.             return TRUE;
  365.         case MB_SELECTION:
  366.             SelectionMsg(wnd, p1, p2);
  367.             break;
  368.         case COMMAND:
  369.             CommandMsg(wnd, p1, p2);
  370.             return TRUE;
  371.         case INSIDE_WINDOW:
  372.             return InsideRect(p1, p2, WindowRect(wnd));
  373.         case CLOSE_POPDOWN:
  374.             ClosePopdownMsg(wnd);
  375.             return TRUE;
  376.         case CLOSE_WINDOW:
  377.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  378.             CloseWindowMsg(wnd);
  379.             return rtn;
  380.         default:
  381.             break;
  382.     }
  383.     return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  384. }
  385.  
  386. /* ------------- reset the MENUBAR -------------- */
  387. static void reset_menubar(WINDOW wnd)
  388. {
  389.     GetText(wnd) = DFrealloc(GetText(wnd), SCREENWIDTH+5);
  390.     memset(GetText(wnd), ' ', SCREENWIDTH);
  391.     *(GetText(wnd)+WindowWidth(wnd)) = '\0';
  392. }
  393.  
  394. static WINDOW GetDocFocus(void)
  395. {
  396.     WINDOW wnd = ApplicationWindow;
  397.     if (wnd != NULL)    {
  398.         wnd = LastWindow(wnd);
  399.         while (wnd != NULL && (GetClass(wnd) == MENUBAR ||
  400.                             GetClass(wnd) == STATUSBAR))
  401.             wnd = PrevWindow(wnd);
  402.         if (wnd != NULL)
  403.             while (wnd->childfocus != NULL)
  404.                 wnd = wnd->childfocus;
  405.     }
  406.     return wnd ? wnd : ApplicationWindow;
  407. }
  408.  
  409.